package com.iamteer.day23;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

/**
主要回顾：网络编程

三要素：
	1. IP 地址：	192.168.1.2（一个 32 位的整数切成了 4 个字节）
	2. 端口号：	
	3. 协议		
	
IP 地址分类：
	A 类：一字节网络号 + 三字节主机号		2^24 个，政府单位
	B 类：两字节网络号 + 两字节主机号		2^16 个，事业单位（学校、银行……）
	C 类：三字节网络号 + 一字节主机号		2^8 个，私人使用（一般组成局域网）

	InetAddress（IP 类）
		常用方法：
			getLocalHost();		//获取本机的 IP 地址对象
			getByName();		//通过 IP、主机名、域名获取 IP 地址对象
			getAllByName();		//获取所有 IP 对象
			getHostAddress();	//返回一个 IP 地址的字符串表示形式
			getHostName();		//返回主机名

端口号的范围：0～65535
	0～1023：系统紧密绑定于一些服务
	1024～49151：松散绑定
	49152～65535：动态或私有


网络通讯协议：
	UDP(User Datagram Protocol)
		1. 将数据及其源和目的封装为数据包，不需要建立连接
		2. 每个数据包大小限制在 64k
		3. 因为无连接，所以不可靠
		4. 因为不需要建立连接，所以速度快
		5. 不分服务端与客户端，只分发送端与接收端
		
	TCP(Transmission Control Protocol)
		1. 面向连接，有特有的通道
		2. 在连接中传输大数据量
		3. 通过三次握手机制连接，可靠协议
		4. 通信前必须建立连接，效率稍低
		5. 区分客户端与服务端

----------------------------------------------------------------------------------------
 UDP Socket：
	DatagramSocket 类 	UDP Socket 服务类
	DatagramPacket 类	UDP 数据包类
		buf
		length
		address
		port
	
	UDP 广播地址：主机号为 255
	如：192.168.1.255
	
----------------------------------------------------------------------------------------
TCP Socket
	Socket 类			//客户端
	ServerSocket 类		//服务端

 */
public class NetWork {

	public static void main(String[] args) throws IOException {
		inetAddress();
	}

	public static void inetAddress() throws UnknownHostException {
		//获取本地的 IP 地址对象
		InetAddress address = InetAddress.getLocalHost();
		System.out.println(address.getHostAddress());
		System.out.println(address.getHostName());
		//根据主机名获取 IP 对象
		address = InetAddress.getByName("homeserver");
		System.out.println(address.getHostAddress());
		System.out.println(address.getHostName());
		//根据域名获取 IP 对象
		address = InetAddress.getByName("www.iamteer.com");
		System.out.println(address.getHostAddress());
		System.out.println(address.getHostName());
		//获取所有 IP 对象
		InetAddress[] ips = InetAddress.getAllByName("www.baidu.com");
		for (InetAddress inetAddress : ips) {
			System.out.println(inetAddress.getHostAddress());
			System.out.println(inetAddress.getHostName());
		}
	}

	public static void udpSend() throws IOException {
		//1. 建立 UPD 服务
		DatagramSocket socket = new DatagramSocket();
		//2. 准备数据
		String data = "hello world...[From Chuck]";
		//3. 把数据封装到数据包中
		DatagramPacket packet = new DatagramPacket(data.getBytes(), data.getBytes().length, InetAddress.getLocalHost(), 9090);
		//4. 发送数据
		socket.send(packet);
		//5. 关闭资源
		socket.close();
	}
	
	public static void udpReceive() throws IOException {
		//1. 建立 UDP 服务，并且监听一个端口
		DatagramSocket socket = new DatagramSocket(9090);
		//2. 准备缓冲区用于接收数据
		byte[] buf = new byte[1024];
		//3. 调用 UDP 服务接收数据包
		DatagramPacket packet = new DatagramPacket(buf, buf.length);
		socket.receive(packet);
		System.out.println(new String(buf, 0, packet.getLength()));
		//4. 关闭资源
		socket.close();
	}

	public static void tcpClient() {
		try {
			//1. 建立 TCP 服务
			Socket socket = new Socket(InetAddress.getLocalHost(), 9090);
			//2. 获取 Socket 输出流
			OutputStream out = socket.getOutputStream();
			//3. 利用输出流对象把数据写出
			out.write("我是客户端。。。".getBytes());
			//4. 关闭资源
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void tcpServer() {
		try {
			//1. 建立 TCP 服务
			ServerSocket serverSocket = new ServerSocket(9090);
			//2. 接受客户端的连接
			Socket socket = serverSocket.accept();
			//2. 获取 Socket 输入流对象
			InputStream in = socket.getInputStream();
			byte[] buf = new byte[1024];
			int length = -1;
			length = in.read(buf);
			System.out.println(new String(buf, 0, length));
			serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
